home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright © 1994 Mikhail Fridberg. Part of this code is copyrighted by Steve Falkenburg
-
- Telnet-based talk server/client
-
- connection management is done through the use of Operating System queues to simplify tracking
- and usage.
- */
-
- #include <CommResources.h>
- #include <Terminals.h>
- #include <Connections.h>
-
- #include <Processes.h>
- #include <MacTCPCommonTypes.h>
- #include <TCPPB.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <time.h>
- #include <stddef.h>
- #include <string.h>
- #include "const.h"
- #include "events.h"
- #include "globals.h"
- #include "utils.h"
- #include "queues.h"
- #include "network.h"
- #include "main.h"
- #include "MacSocket.h"
-
- long recve (TCPiopb *pBlock, char *buf, long len, long flags);
- void StartListener(TCPiopb *pBlock);
- void ListenerCompletion(MyQElemPtr iopb);
- pascal void ResvCompRoutine(MyQElemPtr iopb);
- //void SendData(TCPiopb *pBlock,StringPtr data);
- extern short gRefNum;
- Boolean gNoSendDataPending = TRUE;
-
- /* initialize TCP/IP driver and create our queues, putting them on the unused list
- */
-
- OSErr InitNetwork(void)
- {
- OSErr err;
- TCPiopb *pBlock;
- short i;
-
- err = OpenDriver("\p.ipp",&gTcpDrvrRef);
- gRefNum = gTcpDrvrRef;
- if (err!=noErr)
- return err;
-
- for (i=0; i<kNumConnections; i++) {
- pBlock = (TCPiopb *)GetUnusedPBlock();
- if (pBlock)
- StartListener(pBlock);
- }
-
- return noErr;
- }
-
-
- /* creates a connection end and assigns it to listen for an incoming connection on our
- network port.
- */
-
- void StartListener(TCPiopb *pBlock)
- {
- Ptr rcvBuff;
- OSErr err;
-
- rcvBuff = NewPtr(kRcvBuffSize);
- if (MemError()!=noErr)
- DoError(MemError());
-
- /* create a network stream */
-
- pBlock->csCode = TCPCreate;
- pBlock->ioCRefNum = gTcpDrvrRef;
- pBlock->csParam.create.rcvBuff = rcvBuff;
- pBlock->csParam.create.rcvBuffLen = kRcvBuffSize;
- pBlock->csParam.create.notifyProc = nil;
- err = PBControl(pBlock,false);
- if (err!=noErr)
- DoError(err);
-
- /* create a listener */
-
- pBlock->csCode = TCPPassiveOpen;
- #ifdef __SYSEQU__
- ((MyQElemPtr)pBlock)->savedA5 = *(long *)CurrentA5;
- #else
- ((MyQElemPtr)pBlock)->savedA5 = (long)CurrentA5;
- #endif
- pBlock->ioCompletion = (ProcPtr)ListenerCompletion;
- pBlock->csParam.open.ulpTimeoutValue = 0;
- pBlock->csParam.open.ulpTimeoutAction = 1;
- pBlock->csParam.open.validityFlags = 0xC0;
- pBlock->csParam.open.commandTimeoutValue = 0;
- pBlock->csParam.open.remoteHost = 0;
- pBlock->csParam.open.remotePort = 0;
- pBlock->csParam.open.localHost = 0;
- pBlock->csParam.open.localPort = kGreetingPort;
- pBlock->csParam.open.tosFlags = 0;
- pBlock->csParam.open.precedence = 0;
- pBlock->csParam.open.dontFrag = 0;
- pBlock->csParam.open.timeToLive = 0;
- pBlock->csParam.open.security = 0;
- pBlock->csParam.open.optionCnt = 0;
- pBlock->csParam.receive.rcvBuffLen = 0L;
- PBControl(pBlock,true);
-
- gRunning++; // increment count of running parameter blocks
- }
-
-
- /* called to release all network resources in response to a quit
- */
-
- void CloseNetwork(void)
- {
- THz theZone;
- short drvrRefNum;
- OSErr err;
- TCPiopb tcpBlock;
- StreamPtr *curStream;
- long theStream;
-
- theZone = ApplicZone();
-
- tcpBlock.ioCRefNum = gTcpDrvrRef;
- tcpBlock.csCode = TCPGlobalInfo;
- err = PBControl((ParmBlkPtr)&tcpBlock,false);
- if (err!=noErr)
- return;
-
- curStream = *tcpBlock.csParam.globalInfo.tcpCDBTable;
- while (*curStream) {
-
- theStream = *curStream;
-
- if (PtrZone((Ptr)theStream)==theZone) { // only release streams in our heap
-
- tcpBlock.csCode = TCPStatus;
- tcpBlock.tcpStream = theStream;
- err = PBControl((ParmBlkPtr)&tcpBlock,false);
-
- // abort connection
-
- tcpBlock.csCode = TCPAbort;
- tcpBlock.tcpStream = theStream;
- err = PBControl((ParmBlkPtr)&tcpBlock,false);
-
- // release stream
-
- tcpBlock.csCode = TCPRelease;
- tcpBlock.tcpStream = theStream;
- err = PBControl((ParmBlkPtr)&tcpBlock,false);
- }
-
- curStream++;
- }
- }
-
-
- /* this completion routine will be called when one of the listeners gets a connection from a
- remote machine. since we're using OS queues dispatched from the main event loop, we just
- take the parameter block and put it on the completed queue. if running seven, we call
- WakeUpProcess() to return control to the application
- */
-
- void ListenerCompletion(MyQElemPtr iopb)
- {
- long saveA5;
- ProcessSerialNumber currentProc;
-
- saveA5 = SetA5(iopb->savedA5);
-
- StoreCompletedPBlock(iopb);
- gRunning--;
-
- if (gRunningSeven) {
- WakeUpProcess(&gOurPSN);
- }
-
- SetA5(saveA5);
- }
-
-
- /* this routine is called from the event dispatcher of the event loop to continue processing
- of completed listens received at interrupt time from ListenerCompletion. We send them
- some data, close the connection, and restart the listener, putting it back on MacTCP's queue
- */
-
- void ProcessConnection(MyQElemPtr iopb)
- {
- // Point where; // For choose dialog
- int procID;
- WindowPtr windowRec, windowSend; // the window to create
- Rect theRectRec, theRectSend; // for the terminal bounds
- Str255 toolname = "\pVT102 Tool";
- char *configStr = "FontSize 9 Width 80 Cursor Underline Online True LocalEcho True AutoRepeat True RepeatControls False AutoWrap True NewLine True Scroll Jump ShowControls False SwapBackspaceDelete False TerminalMode VT52 ShowStatusBar False ShowTabRuler False InverseVideo False InsertChar False OriginAtMargin False KeyClick True CursorKey ANSI Keypad Numeric AnswerBack \"\" KeyboardLocked False ActiveCharSet G0 NRCSet USASCII G0 USASCII G1 USASCII G2 USASCII G3 USASCII"
- ;
- int len;
- int err;
-
- SysBeep(1);
- SysBeep(1);
- SysBeep(1);
- SysBeep(1);
- SysBeep(1);
- SysBeep(1);
- SysBeep(1);
- SysBeep(1);
-
- procID = TMGetProcID(toolname);
- windowRec = GetNewWindow(rWindow, NULL, (WindowPtr) -1);
- theRectRec = windowRec->portRect;
- windowSend = GetNewWindow(rWindowSend, NULL, (WindowPtr) -1);
- theRectSend = windowSend->portRect;
- gTermRec = TMNew(&theRectRec, &theRectRec, 0L, procID, windowRec, &TermSendProc,
- NULL, NULL, NULL, &ToolGetConnEnvirons, 0L, 0L);
-
- gTerm = TMNew(&theRectSend, &theRectSend, 0L, procID, windowSend, &TermSendProc,
- NULL, NULL, NULL, &ToolGetConnEnvirons, 0L, 0L);
-
- // SetPt(&where,10,40);
- // TMChoose(&gTerm, where, NULL);
- // configStr = TMGetConfig(gTerm);
- err = TMSetConfig(gTerm, configStr);
- err = TMSetConfig(gTermRec, configStr);
- gGreetingData[(u_short)gGreetingData[0]+1] = '\n';
- (gGreetingData[0]) += 1;
- gGreetingData[(u_short)gGreetingData[0]+1] = 0x00;
- len = gGreetingData[0]+1;
- PtoCstr(gGreetingData);
- send(iopb->tcpBlock.tcpStream, (char *)gGreetingData,
- len, 0L);
- StoreConnectedPBlock(iopb);
- gTimeCount = 1;
- // RecycleFreePBlock(iopb);
- // iopb = GetUnusedPBlock();
- // if (iopb)
- // StartListener(&iopb->tcpBlock);
- }
-
-
- void DoTalking(MyQElemPtr iopb)
- {
- long len;
- int err;
- CMFlags flags = 0L;
- static long deltaTime;
- if (gTimeCount == 1) {
- gTimeCount = 2;
- recve(&iopb->tcpBlock, gRecvBuffer, kRcvBuffSize, 0L);
- }
-
- if ((iopb->tcpBlock.ioResult == 0) &&
- (iopb->tcpBlock.csParam.receive.rcvBuffLen > 0)) {
- len = TMStream(gTermRec,gRecvBuffer, iopb->tcpBlock.csParam.receive.rcvBuffLen, flags);
- recve(&iopb->tcpBlock, gRecvBuffer, kRcvBuffSize, 0L);
- } else
- if ((iopb->tcpBlock.ioResult == 0) &&
- (iopb->tcpBlock.csParam.receive.rcvBuffLen == 0)){
- } else
- if (iopb->tcpBlock.ioResult < 0) {
- printf( "error on recieve: %d",iopb->tcpBlock.ioResult );
- }
-
-
- if (!gNoSendDataPending){
- len = strlen(gSendBuffer);
- err = send(iopb->tcpBlock.tcpStream, gSendBuffer, len, 0L);
- gNoSendDataPending = TRUE;
- }
- TMIdle(gTerm);
- TMIdle(gTermRec);
- }
-
- /* another, acyncronous implementation of recv */
-
- long recve (TCPiopb *pBlock, char *buf, long len, long flags)
- {
- OSErr err;
-
-
- pBlock->ioCRefNum = gRefNum;
- pBlock->csCode = TCPRcv;
- pBlock->ioResult = 1;
- pBlock->ioCompletion = 0L;
- // pBlock->tcpStream = stream;
- pBlock->csParam.receive.commandTimeoutValue = 0x00;
- pBlock->csParam.receive.rcvBuff = buf;
- pBlock->csParam.receive.rcvBuffLen = len;
- PBControl((ParmBlkPtr)pBlock,true);
- return noErr;
-
-
-
- }
-
-
-
-
-
- /* here, we send some data to the remote host over the opened connection and close the connection
- when done. if we didn't use os queues, this code would be much more complicated, since it
- would have to be interrupt safe, and we would have to perform all driver calls async with
- linked completion routines (yuck)
- */
- /*
- void SendData(TCPiopb *pBlock,StringPtr data)
- {
- OSErr err;
- wdsEntry wdsPtr[4];
- char crlf[] = "\015\012";
-
- wdsPtr[0].length = wdsPtr[2].length = 2;
- wdsPtr[0].ptr = wdsPtr[2].ptr = crlf;
- wdsPtr[1].length = data[0];
- wdsPtr[1].ptr = (void *)&data[1];
- wdsPtr[3].length = 0;
- wdsPtr[3].ptr = nil;
-
- pBlock->csCode = TCPSend;
- pBlock->ioCRefNum = gTcpDrvrRef;
- pBlock->csParam.send.ulpTimeoutValue = 0;
- pBlock->csParam.send.ulpTimeoutAction = 1;
- pBlock->csParam.send.validityFlags = 0xc0;
- pBlock->csParam.send.pushFlag = false;
- pBlock->csParam.send.urgentFlag = false;
- pBlock->csParam.send.wdsPtr = (Ptr)wdsPtr;
- err = PBControl(pBlock,false);
- if (err!=noErr)
- DoError(err);
-
- pBlock->csCode = TCPClose;
- pBlock->ioCRefNum = gTcpDrvrRef;
- pBlock->csParam.close.validityFlags = 0xC0;
- pBlock->csParam.close.ulpTimeoutValue = 20;
- pBlock->csParam.close.ulpTimeoutAction = 1;
- err = PBControl(pBlock,false);
- if (err!=noErr)
- DoError(err);
-
- pBlock->csCode = TCPRelease;
- pBlock->ioCRefNum = gTcpDrvrRef;
- err = PBControl(pBlock,false);
- if (err!=noErr)
- DoError(err);
- }
- */